"""
WebService API Classes

This module contains the API classes for WebService CRD, including enums,
specification classes, and the main WebService class.
"""

from enum import Enum
from typing import Optional, List
import datetime
import logging

from kopf import Body
from kubernetes.client.rest import ApiException

# Import constants and utilities
from common import consts
from utils.apis import custom_obj_api
from utils.objs import KubernetesInterface
from utils.spec import get_dict, get_str, get_int, get_list, SpecError


# =============================================================================
# ENUM CLASSES
# =============================================================================

class WebServicePhase(Enum):
    """WebService lifecycle phases."""
    PENDING = "Pending"
    RUNNING = "Running"
    FAILED = "Failed"
    UNKNOWN = "Unknown"
    DELETING = "Deleting"




class DeploymentStatus(Enum):
    """Deployment status values."""
    HEALTHY = "Healthy"
    UNHEALTHY = "Unhealthy"
    PENDING = "Pending"
    UNKNOWN = "Unknown"


class ServiceStatus(Enum):
    """Service status values."""
    HEALTHY = "Healthy"
    UNHEALTHY = "Unhealthy"
    PENDING = "Pending"
    UNKNOWN = "Unknown"


class IngressStatus(Enum):
    """Ingress status values."""
    HEALTHY = "Healthy"
    UNHEALTHY = "Unhealthy"
    PENDING = "Pending"
    UNKNOWN = "Unknown"


class ImagePullPolicy(Enum):
    """Container image pull policies."""
    ALWAYS = "Always"
    IF_NOT_PRESENT = "IfNotPresent"
    NEVER = "Never"


class ServiceType(Enum):
    """Kubernetes service types."""
    CLUSTER_IP = "ClusterIP"
    NODE_PORT = "NodePort"
    LOAD_BALANCER = "LoadBalancer"
    EXTERNAL_NAME = "ExternalName"


class Protocol(Enum):
    """Network protocol types for service ports."""
    TCP = "TCP"
    UDP = "UDP"
    SCTP = "SCTP"


class PathType(Enum):
    """Ingress path matching types."""
    EXACT = "Exact"
    PREFIX = "Prefix"
    IMPLEMENTATION_SPECIFIC = "ImplementationSpecific"


# =============================================================================
# PROBE CLASSES
# =============================================================================

class HTTPGetAction:
    """HTTP GET action for health checks."""
    
    def __init__(self):
        self.path: Optional[str] = None
        self.port: Optional[int] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse HTTP GET action from specification.
        
        Args:
            spec: Dictionary containing the HTTP GET configuration
            prefix: Path prefix for error reporting
        """
        self.path = get_str(spec, "path", prefix)
        self.port = get_int(spec, "port", prefix)

    def validate(self) -> None:
        """Validate HTTP GET action configuration."""
        if not self.path:
            raise SpecError("path is required for HTTPGetAction")
        if not self.port:
            raise SpecError("port is required for HTTPGetAction")


class Probe:
    """Container health probe configuration."""
    
    def __init__(self):
        self.http_get: Optional[HTTPGetAction] = None
        self.initial_delay_seconds: Optional[int] = None
        self.period_seconds: Optional[int] = None
        self.timeout_seconds: Optional[int] = None
        self.failure_threshold: Optional[int] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse probe configuration from specification.
        
        Args:
            spec: Dictionary containing the probe configuration
            prefix: Path prefix for error reporting
        """
        if "httpGet" in spec:
            self.http_get = HTTPGetAction()
            self.http_get.parse(spec["httpGet"], f"{prefix}.httpGet")
        
        self.initial_delay_seconds = get_int(spec, "initialDelaySeconds", prefix, 0)
        self.period_seconds = get_int(spec, "periodSeconds", prefix, 10)
        self.timeout_seconds = get_int(spec, "timeoutSeconds", prefix, 1)
        self.failure_threshold = get_int(spec, "failureThreshold", prefix, 3)

    def validate(self) -> None:
        """Validate probe configuration."""
        if self.http_get:
            self.http_get.validate()
        
        if self.initial_delay_seconds is not None and self.initial_delay_seconds < 0:
            raise SpecError("initialDelaySeconds must be non-negative")
        if self.period_seconds is not None and self.period_seconds < 1:
            raise SpecError("periodSeconds must be at least 1")
        if self.timeout_seconds is not None and self.timeout_seconds < 1:
            raise SpecError("timeoutSeconds must be at least 1")
        if self.failure_threshold is not None and self.failure_threshold < 1:
            raise SpecError("failureThreshold must be at least 1")


# =============================================================================
# CONTAINER CLASSES
# =============================================================================

class ContainerPort:
    """Container port configuration."""
    
    def __init__(self):
        self.container_port: Optional[int] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse container port from specification.
        
        Args:
            spec: Dictionary containing the port configuration
            prefix: Path prefix for error reporting
        """
        self.container_port = get_int(spec, "containerPort", prefix)

    def validate(self) -> None:
        """Validate container port configuration."""
        if self.container_port is None:
            raise SpecError("containerPort is required for ContainerPort")
        if self.container_port < 1 or self.container_port > 65535:
            raise SpecError("containerPort must be between 1 and 65535")


class Container:
    """Container specification for deployment."""
    
    def __init__(self):
        self.name: Optional[str] = None
        self.image: Optional[str] = None
        self.image_pull_policy: Optional[ImagePullPolicy] = None
        self.ports: Optional[List[ContainerPort]] = None
        self.liveness_probe: Optional[Probe] = None
        self.readiness_probe: Optional[Probe] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse container configuration from specification.
        
        Args:
            spec: Dictionary containing the container configuration
            prefix: Path prefix for error reporting
        """
        self.name = get_str(spec, "name", prefix)
        self.image = get_str(spec, "image", prefix)

        if "imagePullPolicy" in spec:
            policy_str = get_str(spec, "imagePullPolicy", prefix)
            self.image_pull_policy = ImagePullPolicy(policy_str)

        if "ports" in spec:
            ports_list = get_list(spec, "ports", prefix)
            self.ports = []
            for i, port_spec in enumerate(ports_list):
                port = ContainerPort()
                port.parse(port_spec, f"{prefix}.ports[{i}]")
                self.ports.append(port)

        if "livenessProbe" in spec:
            self.liveness_probe = Probe()
            self.liveness_probe.parse(spec["livenessProbe"], f"{prefix}.livenessProbe")

        if "readinessProbe" in spec:
            self.readiness_probe = Probe()
            self.readiness_probe.parse(spec["readinessProbe"], f"{prefix}.readinessProbe")

    def validate(self) -> None:
        """Validate container configuration."""
        if not self.name:
            raise SpecError("name is required for Container")
        if not self.image:
            raise SpecError("image is required for Container")

        if self.ports:
            for port in self.ports:
                port.validate()

        if self.liveness_probe:
            self.liveness_probe.validate()

        if self.readiness_probe:
            self.readiness_probe.validate()


# =============================================================================
# DEPLOYMENT SPECIFICATION CLASSES
# =============================================================================

class DeploymentSpec:
    """Deployment specification for WebService."""
    
    def __init__(self):
        self.replicas: Optional[int] = None
        self.containers: Optional[List[Container]] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse deployment configuration from specification.
        
        Args:
            spec: Dictionary containing the deployment configuration
            prefix: Path prefix for error reporting
        """
        self.replicas = get_int(spec, "replicas", prefix, 1)

        containers_list = get_list(spec, "containers", prefix)
        self.containers = []
        for i, container_spec in enumerate(containers_list):
            container = Container()
            container.parse(container_spec, f"{prefix}.containers[{i}]")
            self.containers.append(container)

    def validate(self) -> None:
        """Validate deployment configuration."""
        if self.replicas is not None and self.replicas < 1:
            raise SpecError("replicas must be at least 1")

        if not self.containers:
            raise SpecError("containers are required for DeploymentSpec")

        for container in self.containers:
            container.validate()


# =============================================================================
# SERVICE SPECIFICATION CLASSES
# =============================================================================

class ServicePortSpec:
    """Service port specification."""
    
    def __init__(self):
        self.name: Optional[str] = None
        self.port: Optional[int] = None
        self.target_port: Optional[int] = None
        self.protocol: Optional[Protocol] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse service port from specification.
        
        Args:
            spec: Dictionary containing the port configuration
            prefix: Path prefix for error reporting
        """
        self.name = get_str(spec, "name", prefix)
        self.port = get_int(spec, "port", prefix)
        self.target_port = get_int(spec, "targetPort", prefix)

        if "protocol" in spec:
            protocol_str = get_str(spec, "protocol", prefix)
            self.protocol = Protocol(protocol_str)

    def validate(self) -> None:
        """Validate service port configuration."""
        if not self.name:
            raise SpecError("name is required for ServicePortSpec")
        if self.port is None:
            raise SpecError("port is required for ServicePortSpec")
        if self.target_port is None:
            raise SpecError("targetPort is required for ServicePortSpec")

        if self.port < 1 or self.port > 65535:
            raise SpecError("port must be between 1 and 65535")
        if self.target_port < 1 or self.target_port > 65535:
            raise SpecError("targetPort must be between 1 and 65535")


class ServiceSpec:
    """Service specification for WebService."""
    
    def __init__(self):
        self.type: Optional[ServiceType] = None
        self.ports: Optional[List[ServicePortSpec]] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse service configuration from specification.
        
        Args:
            spec: Dictionary containing the service configuration
            prefix: Path prefix for error reporting
        """
        if "type" in spec:
            type_str = get_str(spec, "type", prefix)
            self.type = ServiceType(type_str)

        ports_list = get_list(spec, "ports", prefix)
        self.ports = []
        for i, service_port in enumerate(ports_list):
            service_port_spec = ServicePortSpec()
            service_port_spec.parse(service_port, f"{prefix}.ports[{i}]")
            self.ports.append(service_port_spec)

    def validate(self) -> None:
        """Validate service configuration."""
        if not self.ports:
            raise SpecError("ports are required for ServiceSpec")

        for port in self.ports:
            port.validate()


# =============================================================================
# INGRESS SPECIFICATION CLASSES
# =============================================================================

class ServiceBackend:
    """Service backend for Ingress."""
    
    def __init__(self):
        self.name: Optional[str] = None
        self.port: Optional[int] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse service backend from specification.
        
        Args:
            spec: Dictionary containing the service backend configuration
            prefix: Path prefix for error reporting
        """
        self.name = get_str(spec, "name", prefix)
        port_spec = get_dict(spec, "port", prefix)
        self.port = get_int(port_spec, "number", f"{prefix}.port")

    def validate(self) -> None:
        """Validate service backend configuration."""
        if not self.name:
            raise SpecError("name is required for ServiceBackend")
        if self.port is None:
            raise SpecError("port is required for ServiceBackend")
        if self.port < 1 or self.port > 65535:
            raise SpecError("port must be between 1 and 65535")


class IngressBackend:
    """Ingress backend configuration."""
    
    def __init__(self):
        self.service: Optional[ServiceBackend] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse ingress backend from specification.
        
        Args:
            spec: Dictionary containing the backend configuration
            prefix: Path prefix for error reporting
        """
        self.service = ServiceBackend()
        self.service.parse(spec["service"], f"{prefix}.service")

    def validate(self) -> None:
        """Validate ingress backend configuration."""
        if not self.service:
            raise SpecError("service is required for IngressBackend")
        self.service.validate()


class HTTPIngressPath:
    """HTTP ingress path configuration."""
    
    def __init__(self):
        self.path: Optional[str] = None
        self.path_type: Optional[PathType] = None
        self.backend: Optional[IngressBackend] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse HTTP ingress path from specification.
        
        Args:
            spec: Dictionary containing the path configuration
            prefix: Path prefix for error reporting
        """
        self.path = get_str(spec, "path", prefix)

        if "pathType" in spec:
            path_type_str = get_str(spec, "pathType", prefix)
            self.path_type = PathType(path_type_str)

        self.backend = IngressBackend()
        self.backend.parse(spec["backend"], f"{prefix}.backend")

    def validate(self) -> None:
        """Validate HTTP ingress path configuration."""
        if not self.path:
            raise SpecError("path is required for HTTPIngressPath")
        if not self.backend:
            raise SpecError("backend is required for HTTPIngressPath")
        self.backend.validate()


class HTTPIngressRuleValue:
    """HTTP ingress rule value."""
    
    def __init__(self):
        self.paths: Optional[List[HTTPIngressPath]] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse HTTP ingress rule value from specification.
        
        Args:
            spec: Dictionary containing the rule value configuration
            prefix: Path prefix for error reporting
        """
        paths_list = get_list(spec, "paths", prefix)
        self.paths = []
        for i, path_spec in enumerate(paths_list):
            path = HTTPIngressPath()
            path.parse(path_spec, f"{prefix}.paths[{i}]")
            self.paths.append(path)

    def validate(self) -> None:
        """Validate HTTP ingress rule value configuration."""
        if not self.paths:
            raise SpecError("paths are required for HTTPIngressRuleValue")
        for path in self.paths:
            path.validate()


class IngressRule:
    """Ingress rule configuration."""
    
    def __init__(self):
        self.http: Optional[HTTPIngressRuleValue] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse ingress rule from specification.
        
        Args:
            spec: Dictionary containing the rule configuration
            prefix: Path prefix for error reporting
        """
        self.http = HTTPIngressRuleValue()
        self.http.parse(spec["http"], f"{prefix}.http")

    def validate(self) -> None:
        """Validate ingress rule configuration."""
        if not self.http:
            raise SpecError("http is required for IngressRule")
        self.http.validate()


class IngressSpec:
    """Ingress specification for WebService."""
    
    def __init__(self):
        self.rules: Optional[List[IngressRule]] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse ingress configuration from specification.
        
        Args:
            spec: Dictionary containing the ingress configuration
            prefix: Path prefix for error reporting
        """
        rules_list = get_list(spec, "rules", prefix)
        self.rules = []
        for i, rule_spec in enumerate(rules_list):
            rule = IngressRule()
            rule.parse(rule_spec, f"{prefix}.rules[{i}]")
            self.rules.append(rule)

    def validate(self) -> None:
        """Validate ingress configuration."""
        if not self.rules:
            raise SpecError("rules are required for IngressSpec")
        for rule in self.rules:
            rule.validate()


# =============================================================================
# QUOTA SPECIFICATION CLASSES
# =============================================================================

class QuotaSpec:
    """Quota specification for WebService resource allocation."""
    
    def __init__(self):
        self.compute_unit: Optional[int] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse quota configuration from specification.
        
        Args:
            spec: Dictionary containing the quota configuration
            prefix: Path prefix for error reporting
        """
        self.compute_unit = get_int(spec, "computeUnit", prefix)

    def validate(self) -> None:
        """Validate quota configuration."""
        if self.compute_unit is None:
            raise SpecError("computeUnit is required for QuotaSpec")
        if self.compute_unit < 1:
            raise SpecError("computeUnit must be at least 1")


# =============================================================================
# WEBSERVICE SPECIFICATION CLASS
# =============================================================================

class WebServiceSpec:
    """WebService specification containing deployment, service, and ingress configurations."""
    
    def __init__(self, namespace: str, name: str, spec: dict):
        """Initialize WebService specification.
        
        Args:
            namespace: Kubernetes namespace
            name: WebService name
            spec: WebService specification dictionary
        """
        self.namespace = namespace
        self.name = name
        self.spec = spec
        self.deployment: Optional[DeploymentSpec] = None
        self.service: Optional[ServiceSpec] = None
        self.ingress: Optional[IngressSpec] = None
        self.quota: Optional[QuotaSpec] = None
        self.load(spec)

    def load(self, spec: dict) -> None:
        """Load and parse WebService specification from dictionary.
        
        Args:
            spec: Dictionary containing the WebService specification
        """
        # Parse deployment configuration
        deployment_spec = get_dict(spec, "deployment", "spec")
        self.deployment = DeploymentSpec()
        self.deployment.parse(deployment_spec, "spec.deployment")

        # Parse service configuration
        service_spec = get_dict(spec, "service", "spec")
        self.service = ServiceSpec()
        self.service.parse(service_spec, "spec.service")

        # Parse ingress configuration
        ingress_spec = get_dict(spec, "ingress", "spec")
        self.ingress = IngressSpec()
        self.ingress.parse(ingress_spec, "spec.ingress")

        # Parse quota configuration
        quota_spec = get_dict(spec, "quota", "spec")
        self.quota = QuotaSpec()
        self.quota.parse(quota_spec, "spec.quota")

    def validate(self) -> None:
        """Validate WebService specification."""
        if not self.deployment:
            raise SpecError("deployment is required for WebServiceSpec")
        if not self.service:
            raise SpecError("service is required for WebServiceSpec")
        if not self.ingress:
            raise SpecError("ingress is required for WebServiceSpec")
        if not self.quota:
            raise SpecError("quota is required for WebServiceSpec")

        self.deployment.validate()
        self.service.validate()
        self.ingress.validate()
        self.quota.validate()


# =============================================================================
# WEBSERVICE STATUS CLASSES
# =============================================================================

class WebServiceStatus:
    """WebService status information (simplified structure as per design)."""
    
    def __init__(self):
        self.phase: Optional[str] = None
        self.observed_generation: Optional[int] = None
        self.last_transition_time: Optional[str] = None
        self.deployment: Optional[dict] = None
        self.service: Optional[dict] = None
        self.ingress: Optional[dict] = None

    def parse(self, spec: dict, prefix: str) -> None:
        """Parse WebService status from specification.
        
        Args:
            spec: Dictionary containing the status configuration
            prefix: Path prefix for error reporting
        """
        if "phase" in spec:
            self.phase = get_str(spec, "phase", prefix)

        if "observedGeneration" in spec:
            self.observed_generation = get_int(spec, "observedGeneration", prefix)

        if "lastTransitionTime" in spec:
            self.last_transition_time = get_str(spec, "lastTransitionTime", prefix)

        if "deployment" in spec:
            self.deployment = get_dict(spec, "deployment", prefix)

        if "service" in spec:
            self.service = get_dict(spec, "service", prefix)

        if "ingress" in spec:
            self.ingress = get_dict(spec, "ingress", prefix)

    def validate(self) -> None:
        """Validate WebService status configuration."""
        if self.phase and self.phase not in [phase.value for phase in WebServicePhase]:
            raise SpecError(f"Invalid phase: {self.phase}")

        if self.observed_generation is not None and self.observed_generation < 0:
            raise SpecError("observedGeneration must be non-negative")

    def to_dict(self) -> dict:
        """Convert status to dictionary."""
        status_dict = {}
        
        if self.phase:
            status_dict["phase"] = self.phase
        if self.observed_generation is not None:
            status_dict["observedGeneration"] = self.observed_generation
        if self.last_transition_time:
            status_dict["lastTransitionTime"] = self.last_transition_time
        if self.deployment:
            status_dict["deployment"] = self.deployment
        if self.service:
            status_dict["service"] = self.service
        if self.ingress:
            status_dict["ingress"] = self.ingress
            
        return status_dict


# =============================================================================
# MAIN WEBSERVICE CLASS
# =============================================================================

class WebService(KubernetesInterface):
    """WebService custom resource for managing web applications with deployment, service, and ingress."""

    def __init__(self, body: Body):
        """Initialize WebService from Kubernetes body.
        
        Args:
            body: Kubernetes resource body
        """
        super().__init__()
        self._obj: Body = body
        self._spec: Optional[WebServiceSpec] = None

    def __str__(self) -> str:
        return f"{self.namespace}/{self.name}"

    def __repr__(self) -> str:
        return f"<WebService {self.name}>"

    @classmethod
    def _get(cls, namespace: str, name: str) -> Body:
        """Get WebService from Kubernetes API."""
        try:
            obj = custom_obj_api.get_namespaced_custom_object(
                group=consts.GROUP,
                version=consts.VERSION,
                plural=consts.WEB_SERVICE_PLURAL,
                namespace=namespace,
                name=name
            )
            return obj
        except ApiException as e:
            raise e

    @classmethod
    def _patch(cls, namespace: str, name: str, patch: dict) -> Body:
        """Patch WebService in Kubernetes API."""
        res = custom_obj_api.patch_namespaced_custom_object(
            group=consts.GROUP,
            version=consts.VERSION,
            plural=consts.WEB_SERVICE_PLURAL,
            namespace=namespace,
            name=name,
            body=patch
        )
        return res

    @classmethod
    def _patch_status(cls, namespace: str, name: str, patch: dict) -> Body:
        """Patch WebService status in Kubernetes API."""
        res = custom_obj_api.patch_namespaced_custom_object_status(
            group=consts.GROUP,
            version=consts.VERSION,
            plural=consts.WEB_SERVICE_PLURAL,
            namespace=namespace,
            name=name,
            body=patch
        )
        return res

    @classmethod
    def read(cls, namespace: str, name: str) -> 'WebService':
        """Read WebService from Kubernetes API."""
        return WebService(cls._get(namespace, name))

    @property
    def metadata(self) -> dict:
        """Get metadata."""
        return self._obj.get("metadata", {})

    @property
    def annotations(self) -> dict:
        """Get annotations."""
        return self.metadata.get("annotations", {})

    @property
    def labels(self) -> dict:
        """Get labels."""
        return self.metadata.get("labels", {})

    @property
    def spec(self) -> dict:
        """Get spec."""
        return self._obj.get("spec", {})

    @property
    def status(self) -> dict:
        """Get status."""
        return self._obj.get("status", {})

    @property
    def name(self) -> str:
        """Get name."""
        return self.metadata.get("name", "")

    @property
    def namespace(self) -> str:
        """Get namespace."""
        return self.metadata.get("namespace", "")

    @property
    def uid(self) -> str:
        """Get UID."""
        return self.metadata.get("uid", "")

    @property
    def is_deleting(self) -> bool:
        """Check if resource is being deleted."""
        return self.metadata.get("deletionTimestamp") is not None

    @property
    def owner_references(self) -> List[dict]:
        """Get owner references."""
        return self.metadata.get("ownerReferences", [])

    def get_create_time(self) -> Optional[datetime.datetime]:
        """Get creation time."""
        create_time_str = self.metadata.get("creationTimestamp")
        if create_time_str:
            return datetime.datetime.fromisoformat(create_time_str.replace('Z', '+00:00'))
        return None

    def self_ref(self, field_path: Optional[str] = None) -> dict:
        """Get self reference for owner references."""
        ref = {
            "apiVersion": consts.API_VERSION,
            "kind": consts.WEB_SERVICE_KIND,
            "name": self.name,
            "uid": self.uid,
            "controller": True,
            "blockOwnerDeletion": True
        }
        if field_path:
            ref["fieldPath"] = field_path
        return ref

    def event_ref(self, field_path: Optional[str] = None) -> dict:
        """Get event reference."""
        ref = {
            "apiVersion": consts.API_VERSION,
            "kind": consts.WEB_SERVICE_KIND,
            "name": self.name,
            "namespace": self.namespace,
            "uid": self.uid
        }
        if field_path:
            ref["fieldPath"] = field_path
        return ref

    def parse_spec(self) -> None:
        """Parse the spec into WebServiceSpec object."""
        self._spec = WebServiceSpec(
            namespace=self.namespace,
            name=self.name,
            spec=self.spec
        )

    def get_spec(self) -> WebServiceSpec:
        """Get the parsed spec."""
        if not self._spec:
            raise RuntimeError("Spec not parsed. Call parse_spec() first.")
        return self._spec

    def update_status(self, status: dict) -> None:
        """Update the status of the WebService."""
        patch = {"status": status}
        try:
            self._patch_status(self.namespace, self.name, patch)
        except ApiException as e:
            raise e

    def logging(self, logger: logging.Logger) -> None:
        """Log WebService information."""
        logger.info(f"WebService: {self.name}")
        logger.info(f"  Namespace: {self.namespace}")
        logger.info(f"  UID: {self.uid}")
        
        if self._spec:
            logger.info(f"  Deployment Replicas: {self._spec.deployment.replicas if self._spec.deployment else 'N/A'}")
            logger.info(f"  Service Type: {self._spec.service.type.value if self._spec.service and self._spec.service.type else 'N/A'}")
            logger.info(f"  Ingress Rules: {len(self._spec.ingress.rules) if self._spec.ingress and self._spec.ingress.rules else 0}")

    def get_deployment_name(self) -> str:
        """Get the name of the managed deployment."""
        return f"{self.name}-deployment"

    def get_service_name(self) -> str:
        """Get the name of the managed service."""
        return f"{self.name}-service"

    def get_ingress_name(self) -> str:
        """Get the name of the managed ingress."""
        return f"{self.name}-ingress"

    def get_status_phase(self) -> Optional[str]:
        """Get current status phase."""
        return self.status.get('phase')

    def is_ready(self) -> bool:
        """Check if the WebService is ready."""
        phase = self.get_status_phase()
        return phase == WebServicePhase.RUNNING.value

    def get_deployment_status(self) -> Optional[dict]:
        """Get deployment status."""
        return self.status.get('deployment')

    def get_service_status(self) -> Optional[dict]:
        """Get service status."""
        return self.status.get('service')

    def get_ingress_status(self) -> Optional[dict]:
        """Get ingress status."""
        return self.status.get('ingress')
